package com.hex.ds.hdrs.warn.service;

import com.google.common.base.Joiner;
import com.hex.bigdata.hbda.base.Page;
import com.hex.bigdata.hbda.domain.User;
import com.hex.bigdata.hbda.service.UserService;
import com.hex.bigdata.hbda.service.dto.UserDto;
import com.hex.bigdata.hbda.service.dto.UserQueryCriteria;
import com.hex.bigdata.hbda.utils.StringUtils;
import com.hex.ds.hdrs.app.dto.AppAdminRelationDto;
import com.hex.ds.hdrs.app.po.AppAdminRelationPo;
import com.hex.ds.hdrs.app.po.AppConf;
import com.hex.ds.hdrs.app.service.IAppAdminRelationService;
import com.hex.ds.hdrs.app.service.impl.AppConfService;
import com.hex.ds.hdrs.app.service.impl.AppUserService;
import com.hex.ds.hdrs.common.annotation.AppCodeVerification;
import com.hex.ds.hdrs.common.constant.Const;
import com.hex.ds.hdrs.common.utils.HdrsDateUtil;
import com.hex.ds.hdrs.common.utils.ListUtil;
import com.hex.ds.hdrs.label.converter.ILabelInfoConverter;
import com.hex.ds.hdrs.label.dto.LabelInfoDto;
import com.hex.ds.hdrs.label.po.LabelInfoPo;
import com.hex.ds.hdrs.label.service.ILabelInfoService;
import org.apache.commons.collections.CollectionUtils;
import com.hex.ds.hdrs.common.utils.BaseUtil;
import com.hex.ds.hdrs.common.utils.MapUtil;
import com.hex.ds.hdrs.warn.dao.WarnConfDao;
import com.hex.ds.hdrs.warn.dto.WarnConfDto;
import com.hex.ds.hdrs.warn.po.WarnConf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lwz
 * @date 2021-01-25
 * @des
 */
@Slf4j
@Service
public class WarnConfService {

    @Autowired
    private WarnConfDao warnConfDao;

    @Autowired
    private UserService userService;

    @Autowired
    private AppUserService appUserService;

    @Autowired
    private WarnConfRegionService warnConfRegionService;

    @Autowired
    private ILabelInfoService labelInfoService;

    @Autowired
    private IAppAdminRelationService appAdminRelationService;

    @Autowired
    private AppConfService appConfService;

    @Autowired
    private ILabelInfoConverter labelInfoConvert;



    public List<WarnConf> qryWarnConfList(WarnConf warnConf, Page page) {
        Map map = MapUtil.Entity2Map(warnConf);
        map.put("appCodeIsNull", true);
        return this.warnConfDao.qryWarnConfList(map, page);
    }

    /**
     * 添加
     *
     * @param warnConfDto
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void add(WarnConfDto warnConfDto) {
        log.debug("【WarnConfService的add】warnConfDto={}", warnConfDto);
        warnConfDto.setPkId(BaseUtil.getPkId());
        // 日期范围
        List<String> startEndDate = warnConfDto.getStartEndDate();
        // 设置开始结束日期
        if (CollectionUtils.isNotEmpty(startEndDate)) {
            warnConfDto.setWarnStDate(startEndDate.get(0).trim());
            warnConfDto.setWarnEndDate(startEndDate.get(1).trim());
        }

        warnConfDto.setToJson(Joiner.on(",").join(warnConfDto.getToUserList()));
        warnConfDto.setRegionJson(Joiner.on(",").join(warnConfDto.getRegionJsonList()));
        warnConfDto.setUpTs(HdrsDateUtil.getCurrentTime());
        warnConfDto.setUpUser(BaseUtil.getUserId());
        this.warnConfRegionService.add(warnConfDto);
        this.warnConfDao.add(warnConfDto);
    }

    /**
     * 查找所有用户
     *
     * @return
     */
    public List<UserDto> getUserList() {
        UserQueryCriteria criteria = new UserQueryCriteria();
        List<UserDto> userList = this.userService.queryAll(criteria);
        return userList;
    }

    /**
     * @Method: del
     * @Param: [pkIds]
     * @Return: void
     * @Description: 删除告警配置
     * @Author: ji.tang
     * @Date: 2022/11/22 14:48
     * @Version: V1.0
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void del(List<String> pkIds) {
        log.debug("【WarnConfService的del】pkIds={}", pkIds);
        if (!pkIds.isEmpty()) {
            for (String pkId : pkIds) {
                this.warnConfRegionService.del(pkId);
                this.warnConfDao.del(pkId);
            }
        }
    }

    /**
     * 通过id查找详细信息
     *
     * @param pkId
     * @return
     */
    public WarnConf getEditWarnConf(String pkId) {
        log.debug("【WarnConfService的getEditWarnConf】pkId={}", pkId);
        WarnConfDto warnConfDto = new WarnConfDto();
        WarnConf warnConf = this.warnConfDao.getEditWarnConf(pkId);
        warnConfDto.setIsWeChatNotic(warnConf.getIsWeChatNotic());
        warnConfDto.setAppCode(warnConf.getAppCode());
        warnConfDto.setIsMailNotic(warnConf.getIsMailNotic());
        warnConfDto.setType(warnConf.getType());
        warnConfDto.setIsSmsNotic(warnConf.getIsSmsNotic());
        warnConfDto.setIsRegionAll(warnConf.getIsRegionAll());
        warnConfDto.setIsValidDate(warnConf.getIsValidDate());
        warnConfDto.setWarnEndDate(warnConf.getWarnEndDate());
        warnConfDto.setWarnStDate(warnConf.getWarnStDate());
        warnConfDto.setParam1(warnConf.getParam1());
        warnConfDto.setParam2(warnConf.getParam2());
        warnConfDto.setParam3(warnConf.getParam3());
        warnConfDto.setParam4(warnConf.getParam4());
        warnConfDto.setParam7(warnConf.getParam7());
        warnConfDto.setParam8(warnConf.getParam8());
        warnConfDto.setParam9(warnConf.getParam9());
        warnConfDto.setIsToSys(warnConf.getIsToSys());
        warnConfDto.setIsToApp(warnConf.getIsToApp());
        warnConfDto.setParam5(warnConf.getParam5());
        warnConfDto.setParam6(warnConf.getParam6());
        warnConfDto.setLabelCode(warnConf.getLabelCode());
        LabelInfoPo labelInfoPo = new LabelInfoPo();
        labelInfoPo.setLabelCode(warnConf.getLabelCode());
        LabelInfoDto labelInfoDto = labelInfoConvert.toLabelInfoDto(labelInfoPo);
        List<LabelInfoPo> labelInfoPoList = labelInfoService.queryList(labelInfoDto);
        if (!ListUtil.isEmpty(labelInfoPoList)) {
            warnConfDto.setLabelName(labelInfoPoList.get(0).getLabelName());
        }
        if (StringUtils.isNotBlank(warnConf.getRegionJson())) {
            warnConfDto.setRegionJsonList(Arrays.asList(warnConf.getRegionJson().split(",")));
        }
        if (StringUtils.isNotBlank(warnConf.getToJson())) {
            warnConfDto.setToUserList(Arrays.asList(warnConf.getToJson().split(",")).stream().map(s -> Integer.parseInt(s.trim())).collect(Collectors.toList()));
        }
        return warnConfDto;
    }

    /**
     * 修改
     *
     * @param warnConfDto
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void edit(WarnConfDto warnConfDto) {
        log.debug("【WarnConfService的edit】warnConfDto={}", warnConfDto);
        // 日期范围
        List<String> startEndDate = warnConfDto.getStartEndDate();
        // 设置开始结束日期
        if (CollectionUtils.isNotEmpty(startEndDate)) {
            warnConfDto.setWarnStDate(startEndDate.get(0).trim());
            warnConfDto.setWarnEndDate(startEndDate.get(1).trim());
        }
        if (warnConfDto.getToUserList() != null) {
            warnConfDto.setToJson(Joiner.on(",").join(warnConfDto.getToUserList()));
        }
        if (warnConfDto.getRegionJsonList() != null) {
            warnConfDto.setRegionJson(Joiner.on(",").join(warnConfDto.getRegionJsonList()));
        }
        warnConfDto.setUpTs(HdrsDateUtil.getCurrentTime());
        warnConfDto.setUpUser(BaseUtil.getUserId());
        this.warnConfRegionService.edit(warnConfDto);
        this.warnConfDao.edit(warnConfDto);
    }


    /**
     * 分页查找应用告警配置
     *
     * @param warnConf
     * @param page
     * @return
     */
    public List<WarnConf> appSelectPages(WarnConf warnConf, Page page) {
        log.debug("【WarnConfService的appSelectPages】的warnConf={}", warnConf.toString());
        Map map = MapUtil.Entity2Map(warnConf);
        List<WarnConf> warnConfs = this.warnConfDao.qryWarnConfList(map, page);
        for (WarnConf warn : warnConfs) {
            LabelInfoPo labelInfoPo = new LabelInfoPo();
            labelInfoPo.setLabelCode(warn.getLabelCode());
            LabelInfoDto labelInfoDto = labelInfoConvert.toLabelInfoDto(labelInfoPo);
            List<LabelInfoPo> labelInfoPos = labelInfoService.queryList(labelInfoDto);
            if (!ListUtil.isEmpty(labelInfoPos)) {
                warn.setLabelName(labelInfoPos.get(0).getLabelName());
            }
        }
        return warnConfs;
    }

    /**
     * 添加应用告警配置
     *
     * @param warnConfDto
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @AppCodeVerification(paramObject = WarnConfDto.class)
    public void addAppWarnConf(WarnConfDto warnConfDto) {
        log.debug("【WarnConfService的addAppWarnConf】warnConfDto={}", warnConfDto);
        warnConfDto.setPkId(BaseUtil.getPkId());
        // 日期范围
        List<String> startEndDate = warnConfDto.getStartEndDate();
        // 设置开始结束日期
        if (CollectionUtils.isNotEmpty(startEndDate)) {
            warnConfDto.setWarnStDate(startEndDate.get(0).trim());
            warnConfDto.setWarnEndDate(startEndDate.get(1).trim());
        }
        warnConfDto.setToJson(Joiner.on(",").join(warnConfDto.getToUserList()));
        warnConfDto.setRegionJson(Joiner.on(",").join(warnConfDto.getRegionJsonList()));
        warnConfDto.setUpTs(HdrsDateUtil.getCurrentTime());
        warnConfDto.setUpUser(BaseUtil.getUserId());
        this.warnConfRegionService.add(warnConfDto);
        this.warnConfDao.add(warnConfDto);
    }

    public List<WarnConf> selectWarnConfList(String type) {
        return this.selectWarnConfList(type, true);
    }

    public List<WarnConf> selectWarnConfList(String type, boolean appCodeIsNull) {
        Map map = new HashMap();
        map.put("type", type);
        map.put("appCodeIsNull", appCodeIsNull);
        return this.warnConfDao.selectWarnConfList(map);
    }

    public List<WarnConf> getOffAgentInfo(String type, String agentCode) {
        Map map = new HashMap();
        map.put("type", type);
        map.put("agentCode", agentCode);
        return this.warnConfDao.getOffAgentInfo(map);
    }

    public List<WarnConf> getAppointTaskWarnList(String appCode, String type, String taskCode, String taskType) {
        Map map = new HashMap();
        map.put("appCode", appCode);
        map.put("type", type);
        map.put("taskCode", taskCode);
        map.put("taskType", taskType);
        return this.warnConfDao.getAppointTaskWarnList(map);
    }

    public Boolean validateParam(WarnConfDto warnConfDto) {
        return this.warnConfDao.validateParam(warnConfDto.getParam9()) > 0;
    }

    /**
     * 获取预警配置获取通知所需要的手机号和邮箱地址
     *
     * @return
     */
    public Map getAgentNoticInf(List<WarnConf> warnConfList, String agentCode) {
        List<String> emailAddresList = new ArrayList<>();
        List<String> phoneList = new ArrayList<>();
        Map noticInfMap = new HashMap();
        for (WarnConf warnConf : warnConfList) {
            List<String> agentCodeList = new ArrayList<>();
            if (StringUtils.isNotBlank(warnConf.getRegionJson())) {
                agentCodeList = Arrays.asList(warnConf.getRegionJson().split(","));
            }
            if ("1".equals(warnConf.getIsRegionAll()) || agentCodeList.contains(agentCode)) {
                List<User> userList = this.getNoticUserList(warnConf);
                if (Const.MAIL_NOTICE_OPEN.equals(warnConf.getIsMailNotic())) {
                    List<String> userMailList = userList.stream().map(User::getEmail).collect(Collectors.toList());
                    emailAddresList.addAll(userMailList);
                    emailAddresList = emailAddresList.stream().distinct().collect(Collectors.toList());
                    noticInfMap.put(Const.WARN_TYPE_MAIL, emailAddresList);
                }
                if (Const.SMS_NOTICE_OPEN.equals(warnConf.getIsSmsNotic())) {
                    List<String> userPhoneList = userList.stream().map(User::getPhone).collect(Collectors.toList());
                    phoneList.addAll(userPhoneList);
                    phoneList = phoneList.stream().distinct().collect(Collectors.toList());
                    noticInfMap.put(Const.WARN_TYPE_MES, phoneList);
                }
            }
        }
        return noticInfMap;
    }

    /**
     * 获取预警配置获取通知所需要的手机号和邮箱地址
     *
     * @return
     */
    public Map getNoticInf(List<WarnConf> warnConfList) {
        List<String> emailAddresList = new ArrayList<>();
        List<String> phoneList = new ArrayList<>();
        Map noticInfMap = new HashMap();
        for (WarnConf warnConf : warnConfList) {
            List<User> userList = this.getNoticUserList(warnConf);
            if (Const.MAIL_NOTICE_OPEN.equals(warnConf.getIsMailNotic())) {
                List<String> userMailList = userList.stream().map(User::getEmail).collect(Collectors.toList());
                emailAddresList.addAll(userMailList);
                emailAddresList = emailAddresList.stream().distinct().collect(Collectors.toList());
                noticInfMap.put(Const.WARN_TYPE_MAIL, emailAddresList);
            }
            if (Const.SMS_NOTICE_OPEN.equals(warnConf.getIsSmsNotic())) {
                List<String> userPhoneList = userList.stream().map(User::getPhone).collect(Collectors.toList());
                phoneList.addAll(userPhoneList);
                phoneList = phoneList.stream().distinct().collect(Collectors.toList());
                noticInfMap.put(Const.WARN_TYPE_MES, phoneList);
            }
        }
        return noticInfMap;
    }

    /**
     * 获取通知对象
     *
     * @param warnConf
     * @return
     */
    public List<User> getNoticUserList(WarnConf warnConf) {
        List<User> userList = new ArrayList<>();
        List<String> userIdList = new ArrayList<>();
        if (Const.IS_TO_SYS.equals(warnConf.getIsToSys())) {
            List<User> users = this.userService.findUserByRole("1");
            userList.addAll(users);
        }
        if (Const.IS_TO_APP.equals(warnConf.getIsToApp())) {
            List<User> users = this.userService.findUserByRole("104");
            userList.addAll(users);
        }
        if (Const.IS_TO_DEP.equals(warnConf.getParam5())) {
            List<User> users = this.userService.findUserByRole("109");
            userList.addAll(users);
        }
        if (Const.IS_TO_MON.equals(warnConf.getParam6())) {
            List<User> users = this.userService.findUserByRole("110");
            userList.addAll(users);
        }
        if (StringUtils.isNotBlank(warnConf.getToJson())) {
            userIdList = Arrays.asList(warnConf.getToJson().split(","));
        }
        if (StringUtils.isNotBlank(warnConf.getToJson())) {
            userIdList = Arrays.asList(warnConf.getToJson().split(","));
        }
        if (StringUtils.isNotBlank(warnConf.getAppCode())) {
            //只通知当前应用下的用户
            List<AppAdminRelationPo> appAdminRelationPos = appAdminRelationService.queryList(new AppAdminRelationDto().setAppCode(warnConf.getAppCode()));
            List<String> userNames = appAdminRelationPos.stream().map(AppAdminRelationPo::getAdminUserCode).distinct().collect(Collectors.toList());
            AppConf appConf = appConfService.qryAppConfByAppCode(warnConf.getAppCode());
            userNames.add(appConf.getAppAdmin());
            //迭代器进行遍历删除元素
            Iterator<User> iterator = userList.iterator();
            while (iterator.hasNext()) {
                User user = iterator.next();
                if (!userNames.contains(user.getUsername())) {
                    iterator.remove();
                }
            }
        }
        for (String userId : userIdList) {
            User noticeUser = this.appUserService.findUserById(Long.valueOf(userId));
            userList.add(noticeUser);
        }
        return userList;
    }

    /**
     * 获取某个预警配置通知所需要的手机号和邮箱地址
     *
     * @param warnConf
     * @return
     */
    public Map getNoticInf(WarnConf warnConf) {
        List<String> emailAddresList = new ArrayList<>();
        List<String> phoneList = new ArrayList<>();
        Map noticInfMap = new HashMap();
        //4.根据配置获取要通知对象（user）
        List<User> userList = this.getNoticUserList(warnConf);
        if (Const.MAIL_NOTICE_OPEN.equals(warnConf.getIsMailNotic())) {
            emailAddresList = userList.stream().map(User::getEmail).collect(Collectors.toList());
            emailAddresList = emailAddresList.stream().distinct().collect(Collectors.toList());
            noticInfMap.put(Const.WARN_TYPE_MAIL, emailAddresList);
        }
        if (Const.SMS_NOTICE_OPEN.equals(warnConf.getIsSmsNotic())) {
            phoneList = userList.stream().map(User::getPhone).collect(Collectors.toList());
            phoneList = phoneList.stream().distinct().collect(Collectors.toList());
            noticInfMap.put(Const.WARN_TYPE_MES, phoneList);
        }
        return noticInfMap;
    }
}
